package com.example.yckjbigdataservice.utils;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.io.compress.Compression;
import org.apache.hadoop.hbase.io.encoding.DataBlockEncoding;
import org.apache.hadoop.hbase.regionserver.BloomType;
import org.apache.hadoop.hbase.util.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * HBase RegionSplitPolicy 六种策略完整实现和表优化配置
 *
 * 六种拆分策略：
 * 1. ConstantSizeRegionSplitPolicy - 固定大小拆分
 * 2. IncreasingToUpperBoundRegionSplitPolicy - 递增拆分（默认）
 * 3. SteppingSplitPolicy - 阶梯式拆分
 * 4. DelimitedKeyPrefixRegionSplitPolicy - 前缀分隔符拆分
 * 5. KeyPrefixRegionSplitPolicy - 键前缀拆分
 * 6. DisabledRegionSplitPolicy - 禁用自动拆分
 */
public class HBaseSplitPolicyManager {

    private static final Logger LOG = LoggerFactory.getLogger(HBaseSplitPolicyManager.class);

    private Connection connection;
    private Admin admin;

    public HBaseSplitPolicyManager() throws IOException {
        Configuration conf = HBaseConfiguration.create();
        // 连接配置
        conf.set("hbase.zookeeper.quorum", "localhost");
        conf.set("hbase.zookeeper.property.clientPort", "2181");

        this.connection = ConnectionFactory.createConnection(conf);
        this.admin = connection.getAdmin();
    }

    /**
     * 1. 固定大小拆分策略
     * 当 region 达到固定大小时进行拆分
     */
    public void createTableWithConstantSizePolicy(String tableName, long maxSize) throws IOException {
        LOG.info("创建表 {} 使用固定大小拆分策略，最大大小: {} MB", tableName, maxSize / 1024 / 1024);

        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
            LOG.warn("表 {} 已存在，先删除", tableName);
            deleteTable(tableName);
        }

        HTableDescriptor tableDesc = new HTableDescriptor(table);

        // 设置拆分策略
        tableDesc.setValue(HTableDescriptor.SPLIT_POLICY,
                "org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy");

        // 设置最大文件大小
        tableDesc.setMaxFileSize(maxSize);

        // 添加列族并优化配置
        HColumnDescriptor cf = createOptimizedColumnFamily("cf1");
        tableDesc.addFamily(cf);

        // 应用通用优化配置
        applyCommonOptimizations(tableDesc);

        admin.createTable(tableDesc);
        LOG.info("表 {} 创建成功", tableName);
    }

    /**
     * 2. 递增到上限拆分策略（HBase 默认策略）
     * 根据表中现有 region 数量动态调整拆分阈值
     */
    public void createTableWithIncreasingToUpperBoundPolicy(String tableName) throws IOException {
        LOG.info("创建表 {} 使用递增到上限拆分策略", tableName);

        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
            deleteTable(tableName);
        }

        HTableDescriptor tableDesc = new HTableDescriptor(table);

        // 设置拆分策略（这是默认策略，可以不显式设置）
        tableDesc.setValue(HTableDescriptor.SPLIT_POLICY,
                "org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy");

        // 设置初始 region 大小和最大大小
        tableDesc.setMaxFileSize(10L * 1024 * 1024 * 1024); // 10GB
        tableDesc.setValue("hbase.increasing.policy.initial.size", "268435456"); // 256MB

        HColumnDescriptor cf = createOptimizedColumnFamily("cf1");
        tableDesc.addFamily(cf);

        applyCommonOptimizations(tableDesc);

        admin.createTable(tableDesc);
        LOG.info("表 {} 创建成功", tableName);
    }

    /**
     * 3. 阶梯式拆分策略
     * 提供更细粒度的拆分大小控制
     */
    public void createTableWithSteppingSplitPolicy(String tableName) throws IOException {
        LOG.info("创建表 {} 使用阶梯式拆分策略", tableName);

        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
            deleteTable(tableName);
        }

        HTableDescriptor tableDesc = new HTableDescriptor(table);

        // 设置拆分策略
        tableDesc.setValue(HTableDescriptor.SPLIT_POLICY,
                "org.apache.hadoop.hbase.regionserver.SteppingSplitPolicy");

        // 阶梯式策略配置
        tableDesc.setMaxFileSize(20L * 1024 * 1024 * 1024); // 20GB 最大值
        tableDesc.setValue("hbase.regionserver.region.split_restriction_type", "BUSY_REGIONS_DELAYED");

        HColumnDescriptor cf = createOptimizedColumnFamily("cf1");
        tableDesc.addFamily(cf);

        applyCommonOptimizations(tableDesc);

        admin.createTable(tableDesc);
        LOG.info("表 {} 创建成功", tableName);
    }

    /**
     * 4. 分隔符前缀拆分策略
     * 根据 RowKey 中的分隔符进行拆分，保持相同前缀的行在同一 region
     */
    public void createTableWithDelimitedKeyPrefixPolicy(String tableName, String delimiter) throws IOException {
        LOG.info("创建表 {} 使用分隔符前缀拆分策略，分隔符: {}", tableName, delimiter);

        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
            deleteTable(tableName);
        }

        HTableDescriptor tableDesc = new HTableDescriptor(table);

        // 设置拆分策略
        tableDesc.setValue(HTableDescriptor.SPLIT_POLICY,
                "org.apache.hadoop.hbase.regionserver.DelimitedKeyPrefixRegionSplitPolicy");

        // 设置分隔符
        tableDesc.setValue("DelimitedKeyPrefixRegionSplitPolicy.delimiter", delimiter);

        // 设置合理的文件大小
        tableDesc.setMaxFileSize(5L * 1024 * 1024 * 1024); // 5GB

        HColumnDescriptor cf = createOptimizedColumnFamily("cf1");
        tableDesc.addFamily(cf);

        applyCommonOptimizations(tableDesc);

        // 根据前缀预分区
        byte[][] splitKeys = generatePrefixSplitKeys(delimiter);

        if (splitKeys.length > 0) {
            admin.createTable(tableDesc, splitKeys);
        } else {
            admin.createTable(tableDesc);
        }

        LOG.info("表 {} 创建成功，预分区数量: {}", tableName, splitKeys.length + 1);
    }

    /**
     * 5. 键前缀拆分策略
     * 根据固定长度的 RowKey 前缀进行拆分
     */
    public void createTableWithKeyPrefixPolicy(String tableName, int prefixLength) throws IOException {
        LOG.info("创建表 {} 使用键前缀拆分策略，前缀长度: {}", tableName, prefixLength);

        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
            deleteTable(tableName);
        }

        HTableDescriptor tableDesc = new HTableDescriptor(table);


        // 设置拆分策略
        tableDesc.setValue(HTableDescriptor.SPLIT_POLICY,
                "org.apache.hadoop.hbase.regionserver.KeyPrefixRegionSplitPolicy");

        // 设置前缀长度
        tableDesc.setValue("KeyPrefixRegionSplitPolicy.prefix_length", String.valueOf(prefixLength));

        tableDesc.setMaxFileSize(8L * 1024 * 1024 * 1024); // 8GB

        HColumnDescriptor cf = createOptimizedColumnFamily("cf1");
        tableDesc.addFamily(cf);

        applyCommonOptimizations(tableDesc);

        // 根据前缀长度预分区
        byte[][] splitKeys = generateFixedPrefixSplitKeys(prefixLength);

        if (splitKeys.length > 0) {
            admin.createTable(tableDesc, splitKeys);
        } else {
            admin.createTable(tableDesc);
        }

        LOG.info("表 {} 创建成功", tableName);
    }

    /**
     * 6. 禁用自动拆分策略
     * 完全禁用自动拆分，需要手动管理 region
     */
    public void createTableWithDisabledSplitPolicy(String tableName, int preRegionCount) throws IOException {
        LOG.info("创建表 {} 禁用自动拆分策略，预分区数量: {}", tableName, preRegionCount);

        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
            deleteTable(tableName);
        }

        HTableDescriptor tableDesc = new HTableDescriptor(table);

        // 设置拆分策略
        tableDesc.setValue(HTableDescriptor.SPLIT_POLICY,
                "org.apache.hadoop.hbase.regionserver.DisabledRegionSplitPolicy");

        // 设置一个很大的文件大小，实际上不会触发拆分
        tableDesc.setMaxFileSize(Long.MAX_VALUE);

        HColumnDescriptor cf = createOptimizedColumnFamily("cf1");
        tableDesc.addFamily(cf);

        applyCommonOptimizations(tableDesc);

        // 手动创建预分区
        byte[][] splitKeys = generateUniformSplitKeys(preRegionCount);

        admin.createTable(tableDesc, splitKeys);
        LOG.info("表 {} 创建成功，预分区数量: {}", tableName, preRegionCount);
    }

    /**
     * 创建优化的列族配置
     */
    private HColumnDescriptor createOptimizedColumnFamily(String cfName) {
        HColumnDescriptor cf = new HColumnDescriptor(cfName);

        // 1. 压缩配置
        cf.setCompressionType(Compression.Algorithm.SNAPPY); // 压缩算法
        cf.setCompactionCompressionType(Compression.Algorithm.SNAPPY); // 压缩合并时使用

        // 2. 数据编码
        //cf.setDataBlockEncoding(DataBlockEncoding.PREFIX_TREE); // 数据块编码
        cf.setDataBlockEncoding(DataBlockEncoding.PREFIX);

        // 3. 布隆过滤器
        cf.setBloomFilterType(BloomType.ROW); // 行级布隆过滤器

        // 4. 缓存配置
        cf.setCacheDataOnWrite(true);  // 写入时缓存数据
        cf.setCacheIndexesOnWrite(true); // 写入时缓存索引
        cf.setCacheBloomsOnWrite(true);  // 写入时缓存布隆过滤器
        cf.setEvictBlocksOnClose(false); // 关闭时不驱逐块

        // 5. 存储策略
        cf.setInMemory(false); // 不强制内存存储（除非是小表）
        cf.setBlockCacheEnabled(true); // 启用块缓存

        // 6. TTL 和版本控制
        cf.setTimeToLive(Integer.MAX_VALUE); // 永不过期，根据业务需求调整
        cf.setMaxVersions(1); // 只保留最新版本，根据需求调整
        cf.setMinVersions(0); // 最小版本数

        // 7. 块大小配置
        cf.setBlocksize(64 * 1024); // 64KB 块大小，适合随机读

        // 8. 压缩配置
        cf.setMobEnabled(false); // 中等对象存储，大value时启用

        return cf;
    }

    /**
     * 应用通用的表级优化配置
     */
    private void applyCommonOptimizations(HTableDescriptor tableDesc) {
        // 1. 内存存储配置
        tableDesc.setMemStoreFlushSize(128 * 1024 * 1024L); // 128MB MemStore 刷写阈值

        // 2. 合并配置
        tableDesc.setValue("hbase.hstore.compactionThreshold", "3"); // 最小合并文件数
        tableDesc.setValue("hbase.hstore.compaction.max", "10"); // 最大合并文件数
        tableDesc.setValue("hbase.hstore.compaction.min.size", "16777216"); // 16MB 最小合并大小
        tableDesc.setValue("hbase.hstore.compaction.max.size", "1073741824"); // 1GB 最大合并大小

        // 3. 读写性能优化
        tableDesc.setValue("hbase.regionserver.handler.count", "30"); // RPC 处理线程数
        tableDesc.setValue("hbase.hregion.majorcompaction", "0"); // 禁用自动 major compaction

        // 4. 缓存优化
        tableDesc.setValue("hfile.block.cache.size", "0.4"); // 块缓存大小
        tableDesc.setValue("hbase.regionserver.global.memstore.size", "0.4"); // MemStore 总大小

        // 5. WAL 优化
        tableDesc.setDurability(Durability.SYNC_WAL); // WAL 同步策略

        // 6. 其他优化
        tableDesc.setValue("hbase.rpc.timeout", "60000"); // RPC 超时时间
        tableDesc.setValue("hbase.client.scanner.timeout.period", "60000"); // 扫描超时
    }

    /**
     * 生成基于分隔符的预分区键
     */
    private byte[][] generatePrefixSplitKeys(String delimiter) {
        List<byte[]> splitKeys = new ArrayList<>();

        // 根据业务场景生成预分区，这里是示例
        String[] prefixes = {"user", "order", "product", "payment", "log"};

        for (int i = 1; i < prefixes.length; i++) {
            splitKeys.add(Bytes.toBytes(prefixes[i] + delimiter));
        }

        return splitKeys.toArray(new byte[splitKeys.size()][]);
    }

    /**
     * 生成固定前缀长度的预分区键
     */
    private byte[][] generateFixedPrefixSplitKeys(int prefixLength) {
        List<byte[]> splitKeys = new ArrayList<>();

        // 根据前缀长度生成十六进制分区
        if (prefixLength <= 2) {
            for (int i = 1; i < 16; i++) {
                String prefix = String.format("%0" + prefixLength + "x", i);
                splitKeys.add(Bytes.toBytes(prefix));
            }
        }

        return splitKeys.toArray(new byte[splitKeys.size()][]);
    }

    /**
     * 生成均匀分布的预分区键
     */
    private byte[][] generateUniformSplitKeys(int regionCount) {
        List<byte[]> splitKeys = new ArrayList<>();

        if (regionCount <= 1) {
            return new byte[0][];
        }

        // 生成十六进制分区键
        long maxKey = (long) Math.pow(16, 4); // 4位十六进制
        long step = maxKey / regionCount;

        for (int i = 1; i < regionCount; i++) {
            String key = String.format("%04x", i * step);
            splitKeys.add(Bytes.toBytes(key));
        }

        return splitKeys.toArray(new byte[splitKeys.size()][]);
    }

    /**
     * 删除表
     */
    private void deleteTable(String tableName) throws IOException {
        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
            admin.disableTable(table);
            admin.deleteTable(table);
            LOG.info("已删除表: {}", tableName);
        }
    }

    /**
     * 演示不同拆分策略的使用
     */
    public void demonstrateAllSplitPolicies() throws IOException {
        LOG.info("开始演示所有拆分策略...");

        try {
            // 1. 固定大小拆分
            createTableWithConstantSizePolicy("constant_size_table", 1024 * 1024 * 1024L); // 1GB

            // 2. 递增拆分
            createTableWithIncreasingToUpperBoundPolicy("increasing_table");

            // 3. 阶梯式拆分
            createTableWithSteppingSplitPolicy("stepping_table");

            // 4. 分隔符前缀拆分
            createTableWithDelimitedKeyPrefixPolicy("delimited_prefix_table", "|");

            // 5. 键前缀拆分
            createTableWithKeyPrefixPolicy("key_prefix_table", 4);

            // 6. 禁用拆分
            createTableWithDisabledSplitPolicy("disabled_split_table", 10);

            LOG.info("所有拆分策略演示完成");

        } catch (Exception e) {
            LOG.error("演示过程中出现错误", e);
            throw e;
        }
    }

    /**
     * 针对不同业务场景的表创建建议
     */
    public void createTableForScenario(String scenario, String tableName) throws IOException {
        switch (scenario.toLowerCase()) {
            case "oltp":
                createOLTPOptimizedTable(tableName);
                break;
            case "olap":
                createOLAPOptimizedTable(tableName);
                break;
            case "timeseries":
                createTimeSeriesOptimizedTable(tableName);
                break;
            case "log":
                createLogOptimizedTable(tableName);
                break;
            default:
                LOG.warn("未知场景: {}, 使用默认配置", scenario);
                createTableWithIncreasingToUpperBoundPolicy(tableName);
        }
    }

    /**
     * OLTP 场景优化表
     * 特点：频繁随机读写，低延迟要求
     */
    private void createOLTPOptimizedTable(String tableName) throws IOException {
        LOG.info("创建 OLTP 优化表: {}", tableName);

        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
            deleteTable(tableName);
        }

        HTableDescriptor tableDesc = new HTableDescriptor(table);

        // OLTP 使用固定大小拆分，避免拆分带来的延迟抖动
        tableDesc.setValue(HTableDescriptor.SPLIT_POLICY,
                "org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy");
        tableDesc.setMaxFileSize(2L * 1024 * 1024 * 1024); // 2GB，较小的region

        // OLTP 优化的列族
        HColumnDescriptor cf = new HColumnDescriptor("cf1");
        cf.setCompressionType(Compression.Algorithm.LZ4); // 快速压缩
        cf.setDataBlockEncoding(DataBlockEncoding.FAST_DIFF); // 快速编码
        cf.setBloomFilterType(BloomType.ROW); // 行布隆过滤器
        cf.setBlocksize(16 * 1024); // 16KB 小块，适合随机读
        cf.setCacheDataOnWrite(true);
        cf.setMaxVersions(1); // 只保留最新版本
        cf.setInMemory(true); // 热数据内存存储

        tableDesc.addFamily(cf);

        // OLTP 优化配置
        tableDesc.setMemStoreFlushSize(64 * 1024 * 1024L); // 64MB，减少flush频率
        tableDesc.setValue("hbase.hstore.compactionThreshold", "4");
        tableDesc.setValue("hbase.hregion.majorcompaction", "86400000"); // 1天一次major compaction
        tableDesc.setDurability(Durability.SYNC_WAL); // 强一致性

        // 预分区，避免热点
        byte[][] splitKeys = generateUniformSplitKeys(16);
        admin.createTable(tableDesc, splitKeys);

        LOG.info("OLTP 优化表 {} 创建成功", tableName);
    }

    /**
     * OLAP 场景优化表
     * 特点：大批量扫描，分析查询
     */
    private void createOLAPOptimizedTable(String tableName) throws IOException {
        LOG.info("创建 OLAP 优化表: {}", tableName);

        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
            deleteTable(tableName);
        }

        HTableDescriptor tableDesc = new HTableDescriptor(table);

        // OLAP 使用递增拆分，允许大region
        tableDesc.setValue(HTableDescriptor.SPLIT_POLICY,
                "org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy");
        tableDesc.setMaxFileSize(20L * 1024 * 1024 * 1024); // 20GB 大region

        // OLAP 优化的列族
        HColumnDescriptor cf = new HColumnDescriptor("cf1");
        cf.setCompressionType(Compression.Algorithm.SNAPPY); // 高压缩比
        cf.setDataBlockEncoding(DataBlockEncoding.PREFIX); // 高压缩编码
        cf.setBloomFilterType(BloomType.ROWCOL); // 行列布隆过滤器
        cf.setBlocksize(256 * 1024); // 256KB 大块，适合扫描
        cf.setCacheDataOnWrite(false); // 不缓存写入数据
        cf.setMaxVersions(1);
        cf.setInMemory(false);

        tableDesc.addFamily(cf);

        // OLAP 优化配置
        tableDesc.setMemStoreFlushSize(256 * 1024 * 1024L); // 256MB，减少文件数
        tableDesc.setValue("hbase.hstore.compactionThreshold", "2"); // 减少小文件
        tableDesc.setValue("hbase.hregion.majorcompaction", "0"); // 手动控制major compaction
        tableDesc.setDurability(Durability.ASYNC_WAL); // 异步WAL，提高写入性能

        admin.createTable(tableDesc);
        LOG.info("OLAP 优化表 {} 创建成功", tableName);
    }

    /**
     * 时序数据优化表
     * 特点：按时间顺序写入，范围查询
     */
    private void createTimeSeriesOptimizedTable(String tableName) throws IOException {
        LOG.info("创建时序数据优化表: {}", tableName);

        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
            deleteTable(tableName);
        }

        HTableDescriptor tableDesc = new HTableDescriptor(table);

        // 时序数据使用前缀拆分，按时间分区
        tableDesc.setValue(HTableDescriptor.SPLIT_POLICY,
                "org.apache.hadoop.hbase.regionserver.KeyPrefixRegionSplitPolicy");
        tableDesc.setValue("KeyPrefixRegionSplitPolicy.prefix_length", "8"); // 8位时间前缀
        tableDesc.setMaxFileSize(10L * 1024 * 1024 * 1024); // 10GB

        // 时序优化的列族
        HColumnDescriptor cf = new HColumnDescriptor("metrics");
        cf.setCompressionType(Compression.Algorithm.SNAPPY);
        cf.setDataBlockEncoding(DataBlockEncoding.DIFF); // 差分编码，适合时序数据
        cf.setBloomFilterType(BloomType.NONE); // 时序数据通常不需要布隆过滤器
        cf.setBlocksize(128 * 1024); // 128KB
        cf.setMaxVersions(1);
        cf.setTimeToLive(30 * 24 * 3600); // 30天TTL

        tableDesc.addFamily(cf);

        // 时序优化配置
        tableDesc.setMemStoreFlushSize(128 * 1024 * 1024L);
        tableDesc.setValue("hbase.hstore.compactionThreshold", "3");
        tableDesc.setDurability(Durability.ASYNC_WAL);

        // 按时间预分区
        byte[][] splitKeys = generateTimeBasedSplitKeys();
        admin.createTable(tableDesc, splitKeys);

        LOG.info("时序数据优化表 {} 创建成功", tableName);
    }

    /**
     * 日志数据优化表
     * 特点：写多读少，大批量写入
     */
    private void createLogOptimizedTable(String tableName) throws IOException {
        LOG.info("创建日志数据优化表: {}", tableName);

        TableName table = TableName.valueOf(tableName);
        if (admin.tableExists(table)) {
            deleteTable(tableName);
        }

        HTableDescriptor tableDesc = new HTableDescriptor(table);

        // 日志数据使用分隔符拆分，按日志类型分区
        tableDesc.setValue(HTableDescriptor.SPLIT_POLICY,
                "org.apache.hadoop.hbase.regionserver.DelimitedKeyPrefixRegionSplitPolicy");
        tableDesc.setValue("DelimitedKeyPrefixRegionSplitPolicy.delimiter", "_");
        tableDesc.setMaxFileSize(15L * 1024 * 1024 * 1024); // 15GB

        // 日志优化的列族
        HColumnDescriptor cf = new HColumnDescriptor("log");
        cf.setCompressionType(Compression.Algorithm.GZ); // 高压缩比
        cf.setDataBlockEncoding(DataBlockEncoding.PREFIX);
        cf.setBloomFilterType(BloomType.NONE); // 日志通常顺序访问
        cf.setBlocksize(1024 * 1024); // 1MB 大块
        cf.setMaxVersions(1);
        cf.setTimeToLive(7 * 24 * 3600); // 7天TTL
        cf.setInMemory(false);
        cf.setCacheDataOnWrite(false); // 不缓存日志数据

        tableDesc.addFamily(cf);

        // 日志优化配置
        tableDesc.setMemStoreFlushSize(512 * 1024 * 1024L); // 512MB，减少flush
        tableDesc.setValue("hbase.hstore.compactionThreshold", "10"); // 允许更多小文件
        tableDesc.setDurability(Durability.SKIP_WAL); // 跳过WAL，提高写入性能

        // 按日志类型预分区
        String[] logTypes = {"error", "info", "warn", "debug", "access"};
        List<byte[]> splitKeys = new ArrayList<>();
        for (int i = 1; i < logTypes.length; i++) {
            splitKeys.add(Bytes.toBytes(logTypes[i] + "_"));
        }

        admin.createTable(tableDesc, splitKeys.toArray(new byte[splitKeys.size()][]));
        LOG.info("日志数据优化表 {} 创建成功", tableName);
    }

    /**
     * 生成基于时间的预分区键
     */
    private byte[][] generateTimeBasedSplitKeys() {
        List<byte[]> splitKeys = new ArrayList<>();

        // 按小时分区，生成24小时的分区
        //for
        return splitKeys.toArray(new byte[splitKeys.size()][]);
    }
}

